package ua.epam.muzalevskiy.traction.dao;

import java.util.List;
import ua.epam.muzalevskiy.traction.dao.exceptions.NotExistsParameterException;
import ua.epam.muzalevskiy.traction.dao.exceptions.NotUniqueParameterException;
import ua.epam.muzalevskiy.traction.route.Stop;
import ua.epam.muzalevskiy.traction.route.Route;
import ua.epam.muzalevskiy.traction.vehicle.Vehicle;
import ua.epam.muzalevskiy.traction.vehicle.VehicleType;

/**
 * This interface defines methods that needed to select, insert, update, delete
 * data from DataBase.
 *
 * @author Muzalevskiy Vitaliy
 */
public interface RouteDao {    
            
    /**
     * Add new <code> Route </code> value to DataBase.
     *
     * @param route - concrete <code> Route </code> value.     
     * @throws NotUniqueRouteNumberException if <code> Route </code> with
     *      such <code> routeNumber </code> already exists in DataBase.
     */
    void addRoute(Route route) throws NotUniqueParameterException;
    
    /**
     * Selects all Routes in DataBase. 
     *
     * @return <code> List </code> of <code> Routes </code>..
     */
    List<Route> selectAll();
    
    /**
     * Select <code> Route </code> with concrete <code> routeNumber </code>.
     *
     * @param routeNumber <code> routeNumber </code> value of the
     *      <code> Route </code> needed to select.
     * @return <code> Route </code> type value with required 
     *      <code> routeNumber </code>.
     */
    Route selectRouteByNumber(String routeNumber);
    
    /**
     * Select <code> Route </code> with concrete <code> routeID </code>.
     *
     * @param routeID <code> routeNumber </code> value of the
     *      <code> Route </code> needed to select.
     * @return <code> Route </code> type value with required 
     *      <code> routeNumber </code>.
     */
    Route selectRouteByID(int routeID);
    
    /**
     * Selects all Routes in DataBase where <code> VehicleType </code> value
     * equals <code> VehicleType.BUS </code>.
     *
     * @return <code> List </code> of <code> Routes </code>. The values of 
     *      included collections equals <code> null </code>.
     * @see VehicleType
     */
    List<Route> selectBusRoutes();
    
    /**
     * Selects all Routes in DataBase where <code> VehicleType </code> value
     * equals <code> VehicleType.TROLLETBUS </code>.
     *
     * @return <code> List </code> of <code> Routes </code>. The values of 
     *      included collections equals <code> null </code>.
     * @see VehicleType
     */
    List<Route> selectTrolleybusRoutes();
    
    /**
     * Selects all Routes in DataBase where <code> VehicleType </code> value
     * equals <code> VehicleType.TRAM </code>.
     *
     * @return <code> List </code> of <code> Routes </code>. The values of 
     *      included collections equals <code> null </code>.
     * @see VehicleType
     */
    List<Route> selectTramRoutes();
    
    /**
     * Delete <code> Route </code> with such <code> routeNumber </code>.
     * 
     * @param routeNumber <code> routeNumber </code> value of the
     *      <code> Route </code> needed to delete.
     * @throws NotExistsRouteNumberException if <code> Route </code> with
     *      such <code> routeNumber </code> don't exists in DataBase.
     */
    void deleteRouteByID(int routeID) 
            throws NotExistsParameterException;
    
    /**
     * @param routeNumber <code> routeNumber </code> value of the
     *      <code> Route </code>.
     * @return List of <code> Stop </code> type values that current 
     *      <code> Route </code> include.
     */
    List<Stop> getRouteStops(int routeNumber);
    
    /**
     * @param routeNumber <code> routeNumber </code> value of the
     *      <code> Route </code>.
     * @return List of <code> Vehicle </code> type values that current 
     *      <code> Route </code> include.
     * @see Stop
     */
    List<Vehicle> getRouteVehicles(int routeNumber);
    
    /**
     * Method designed to increase the <code> Stop </code> number in a
     * <code> Route </code>. 
     *
     * @param routeNumber <code> routeNumber </code> value of the
     *      <code> Route </code>.
     * @param number - number of current <code> Stop </code> in stop list.
     * @param stopID - identifier of <code> Stop </code> that will be added to
     *      current <code> Route </code>.
     * @see Vehicle
     */
    void addStop(int routeNumber, int number, int stopID);
    
    /**
     * Deletes <code> Stop </code> with entered <code> int </code> value as
     * <code> stopID </code>. 
     *
     * @param routeNumber <code> routeNumber </code> value of the
     *      <code> Route </code>.
     * @param stopID - identifier of <code> Stop </code> that will be deleted
     *      from current <code> Route </code>.
     * @see Stop
     */
    void deleteStop(int routeNumber, int stopID);
    
    /**
     * Returns the number that <code> Stop </code> with such ID takes in
     * stop list of current <code> Route </code>.
     *
     * @param routeNumber <code> routeNumber </code> value of the
     *      <code> Route </code>.
     * @param stopID - identifier of <code> Stop </code> in DataBase. 
     * @return number of <code> Stop </code> in current <code> Route </code>.
     * @see Stop
     */
    Integer getStopNumber(int routeNumber, int stopID);
}
